home *** CD-ROM | disk | FTP | other *** search
- /* ------------------------------------------------------------------
- MML compiler [M2]
- programmed by S.Yamamoto (SHINNOSUKE)
- m2ctrl.c -- control line
- ------------------------------------------------------------------ */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #include <limits.h>
- #include "m2.h"
-
- #define SUCCSESS 0
- #define FAILURE (-1)
- #define TRUE 1
- #define FALSE 0
- #define ERR (-1)
- #define YES 1
- #define NO 0
-
- /* ROLAND EXCLUSIVE SUM 計算 */
- #define CHECKSUM(x) (((x)%128!=0)?128-(x)%128:0)
-
- static char *ctrlCommand[] = {
- "title",
- "copyright",
- "compile",
- "begin",
- "tempo",
- "signature",
- "malloc",
- "division",
- "part",
- "rhmPart",
- "rhmNote",
- "program",
- "memo",
- "\0"
- };
-
- void makeHeader(int d) /* SMFヘッダ */
- {
- int d1;
- int d2;
-
- d1 = (d & 0xff00) >> 8;
- d2 = d & 0xff;
-
- putData( 14 ,'M' ,'T' ,'h'
- ,'d' ,0 ,0 ,0 ,6 ,0 ,0 ,0 ,1 ,d1 ,d2);
- putData( 8 ,'M' ,'T' ,'r' ,'k' ,0 ,0 ,0 ,0);
- return;
- }
-
- void varNum( unsigned long n ) /* 可変長数値表現 */
- {
- int i;
- int flags = NO;
- int d[4]; /* 上限4バイト */
-
- for( i=0;i<4;i++ )
- d[i] = (int)(( n >> (i*7)) & 0x7f );
-
- for( i=3;i>=0;i-- ) {
- if( flags == NO && d[i] == 0 && i != 0)
- continue;
- flags = YES;
- putData( 1,(( i==0 ) ? d[i] : d[i] | 0x80));
- }
- return;
- }
-
- void putText( char *t ) /* テキスト情報を書き込む */
- {
- int i;
- int l;
-
- l = strlen(t);
- varNum( l );
- for( i=0;i<l;i++ )
- putData( 1 ,*(t+i) );
- return;
- }
-
- void putTempo( int t ) /* テンポを書き込む */
- {
- int tempo1;
- int tempo2;
- int tempo3;
- unsigned long tempo;
-
- tempo = 60000000 / (unsigned long) t;
-
- tempo1 = (int) (( tempo & 0xff0000 ) >> 16 );
- tempo2 = (int) (( tempo & 0xff00 ) >> 8 );
- tempo3 = (int) ( tempo & 0xff );
-
- putData( 6 ,0xff ,0x51 ,0x03 ,tempo1 ,tempo2 ,tempo3 );
- return;
- }
-
- void putSignature( int n,int d ) /* 拍子を書き込む */
- {
- int i;
- int dummy;
- int denom=ERR;
-
- for( i=0;i<7;i++ ) {
- dummy = power( 2 ,i );
- if( d == dummy ) {
- denom = i;
- break;
- }
- }
-
- if( denom == ERR) denom = 2;
- putData( 7 ,0xff ,0x58 ,0x04 ,n ,denom ,0x18 ,0x08 );
- return;
- }
-
- FLGDAT ctrlLine( void ) /* コントロール行メイン */
- {
- char *param = "param";
- char *buf;
- char *rp;
- char text[3][128];
-
- int i;
- int j;
- int dummy;
- int n;
- int endFlags = NO;
-
- int sigNum = ERR;
- int sigDen;
-
- FLGDAT fgset;
-
- strcpy( text[0] ,"no title" );
- strcpy( text[1] ,"no copyright" );
- strcpy( text[2] ,"created by MML compiler [M2] V2.X" );
-
- fgset.tempo = 120; /* 初期状態 テンポ */
- fgset.wksize = 2048; /* イベント数 */
- fgset.rpart = -1;
- fgset.div = 48; /* 分解能 */
- fgset.signature[0] = 4;
- fgset.signature[1] = 4;
-
- for( i=0;i<16;i++ ) fgset.part[i] = i;
- for( i=0;i<=128;i++ ) fgset.program[i] = i;
-
- for( j=0;j<2;j++ )
- for( i=0;i<26;i++ )
- fgset.rnote[i][j] = ERR;
-
- do {
- if(( buf=Pre_fgets() ) == NULL )
- errMsg( MSG_freerr ,"No MML data" );
- rp = skipSpace( buf );
- if( *rp == '\0' )
- continue;
- if( *rp != '.' )
- errMsg( MSG_syntax ,"control" );
- rp = skipSpace( ++rp );
- n = comSearch( ctrlCommand ,rp );
- if( n == ERR )
- errMsg( MSG_undctl ,NULL );
- rp += strlen( ctrlCommand[n] );
- rp = skipSpace( rp );
-
- switch( n ) {
- case 0:
- case 1:
- strncpy( text[n] ,rp ,127);
- break;
- case 2:
- case 3:
- endFlags = YES;
- break;
- case 4:
- fgset.tempo = strToInt( &rp,30,600,0,NULL );
- break;
- case 5:
- sigNum = strToInt( &rp,1,64,-1,NULL );
- rp = skipSpace( rp );
- if( *rp == '/' ) rp++;
- sigDen = strToInt( &rp,1,64,-1,NULL );
- break;
- case 6:
- fgset.wksize = strToInt( &rp,1,INT_MAX,0,NULL );
- break;
- case 7:
- fgset.div = strToInt( &rp,48,480,0,NULL );
- break;
- case 8:
- rp = skipSpace( rp );
- dummy = strToInt( &rp,1,16,-1,NULL ) - 1;
- rp = skipSpace( rp );
- if( *rp == ',' ) rp++;
- fgset.part[dummy] = strToInt( &rp,1,16,-1,NULL ) - 1;
- break;
- case 9:
- fgset.rpart = strToInt( &rp,1,16,-1,NULL ) - 1;
- break;
- case 10:
- dummy = toupper( *rp );
- if( dummy<'A' || dummy>'Z' || dummy == 'R' )
- errMsg(MSG_misopd,param);
- dummy -= 'A';
- rp++;
- for( i=0;i<2;i++ ) {
- rp = skipSpace( rp );
- if( *rp==',' ) rp++;
- fgset.rnote[dummy][i] = strToInt( &rp,0,127,-1,NULL );
- }
- break;
- case 11:
- rp = skipSpace( rp );
- dummy = strToInt( &rp,0,128,-1,NULL );
- rp = skipSpace( rp );
- if( *rp == ',' ) rp++;
- fgset.program[dummy] = strToInt( &rp,1,128,-1,NULL );
- break;
- }
- } while( endFlags == NO );
-
- makeHeader( fgset.div );
-
- for( i=0;i<3;i++ ) {
- putData( 3,0,0xff,i+1 );
- putText( text[i] );
- }
-
- putDisp( "Title :%s\n",text[0] );
- putDisp( "Copyright :%s\n",text[1] );
- putDisp( "Division :%d\n",fgset.div );
- putDisp( "Rhythm MML :" );
- if( fgset.rpart == -1 )
- putDisp( "OFF\n" );
- else putDisp( "ON (part %d)\n",fgset.rpart + 1 );
-
- putData( 1,0 );
- putTempo( fgset.tempo );
-
- putDisp( "Top tempo :%d\n",fgset.tempo );
-
- if( sigNum != ERR ) {
- putData( 1,0 );
- putSignature( sigNum,sigDen );
- fgset.signature[0] = sigNum;
- fgset.signature[1] = sigDen;
- putDisp( "Signature :%d/%d\n",sigNum,sigDen );
- }
-
-
- return( fgset );
- }
-